# @Version        : 1.0
# @Update Time    : 2025/9/15 21:57
# @File           : memory.py
# @IDE            : PyCharm
# @Desc           : 文件描述信息
import time
from typing import Any, Type, TypeVar, List
from typing import Optional

from .base import AuthDaoByStringFollowObject

T = TypeVar("T")


class MemoryAuthDao(AuthDaoByStringFollowObject):
    """基于内存的实现，适合StringFollowObject模式（异步版本）"""

    def __init__(self):
        self._storage = {}
        self._timeouts = {}
        self._create_times = {}

    # 实现Object操作相关方法
    async def get_object(
        self, key: str, class_type: Optional[Type[T]] = None
    ) -> Optional[Any]:
        if key in self._storage and self._is_not_expired(key):
            return self._storage[key]
        return None

    async def set_object(self, key: str, obj: Any, timeout: int):
        self._storage[key] = obj
        self._create_times[key] = time.time()

        if timeout == self.NEVER_EXPIRE:
            # 永不过期，不设置超时
            if key in self._timeouts:
                del self._timeouts[key]
        elif timeout > 0:
            # 设置超时时间
            self._timeouts[key] = time.time() + timeout
        else:
            # 不存储或无效超时时间
            if key in self._timeouts:
                del self._timeouts[key]
            if timeout != 0:  # 0表示不存储
                await self.delete_object(key)

    async def update_object(self, key: str, obj: Any):
        if key in self._storage:
            self._storage[key] = obj

    async def delete_object(self, key: str):
        if key in self._storage:
            del self._storage[key]
        if key in self._timeouts:
            del self._timeouts[key]
        if key in self._create_times:
            del self._create_times[key]

    async def get_object_timeout(self, key: str) -> int:
        if key not in self._storage:
            return self.NOT_VALUE_EXPIRE

        if key not in self._timeouts:
            return self.NEVER_EXPIRE

        remaining = self._timeouts[key] - time.time()
        return max(0, int(remaining))

    async def update_object_timeout(self, key: str, timeout: int):
        if key not in self._storage:
            return

        if timeout == self.NEVER_EXPIRE:
            if key in self._timeouts:
                del self._timeouts[key]
        elif timeout > 0:
            self._timeouts[key] = time.time() + timeout
        else:
            await self.delete_object(key)

    async def search_data(
        self, prefix: str, keyword: str, start: int, size: int, sort_type: bool
    ) -> List[str]:
        results = []
        for key in self._storage.keys():
            if key.startswith(prefix) and keyword in key:
                results.append(key)

        # 排序
        results.sort(reverse=not sort_type)

        # 分页
        if size == -1:
            return results[start:]
        else:
            return results[start : start + size]

    def _is_not_expired(self, key: str) -> bool:
        """检查键是否未过期"""
        if key not in self._timeouts:
            return True
        return time.time() < self._timeouts[key]
